package com.okilo.online.app.fmt

import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Typeface
import android.provider.ContactsContract
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.okilo.online.app.R
import com.okilo.online.app.act.OkiloProcessStepsAct
import com.okilo.online.app.common.OkiloComFmt
import com.okilo.online.app.configs.OkiloConfigs.addParams
import com.okilo.online.app.databinding.OkiloFmtStepContactBinding
import com.okilo.online.app.event.OkiloEventData
import com.okilo.online.app.event.OkiloEventPointType
import com.okilo.online.app.event.room.OkiloPointManager
import com.okilo.online.app.tools.OkiloDensityUtil
import com.okilo.online.app.tools.decoration.LinearSpacingItemDecoration
import com.okilo.online.app.tools.log.OkiloLog
import com.okilo.online.app.apt.OkiloStepContactApt
import org.json.JSONArray
import org.json.JSONObject
import java.util.regex.Pattern

/**
 * OkiloLoan
 * @Author wwdeng
 * @CreateTime: 2024/11/19 10:38
 * @Annotation：认证流程 - 联系人
 */
class OkiloStepContactFmt(): OkiloComFmt() {
    private var _binding: OkiloFmtStepContactBinding? = null

    private var contactAdapter: OkiloStepContactApt? = null

    private var authStepAct: OkiloProcessStepsAct? = null
    private var stepItem: JSONObject? = null

    override var pageName: String = "contact_info"

    constructor(act: OkiloProcessStepsAct, stepItem: JSONObject): this(){
        this.authStepAct = act
        this.stepItem = stepItem
        pageName = "${stepItem.optString("stepTitle")}_Page"
    }

    override fun createOkiloContentView(inflater: LayoutInflater): View? {
        _binding = OkiloFmtStepContactBinding.inflate(inflater)
        return _binding?.root
    }

    override fun initializeOkiloViews() {
        val showKey = getString(R.string.okilo_process_step_contact_info_tips_repay_on_time)
        val showText = String.format(getString(R.string.okilo_process_step_contact_info_tips),showKey)
        val startIndex = showText.indexOf(showKey)
        val contactTipsSpannable = SpannableString(showText)
        contactTipsSpannable.setSpan(ForegroundColorSpan(getColor(R.color.okilo_color_ff0084a2)), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        //加粗
        contactTipsSpannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        _binding?.okiloContactDataSecurity?.text = contactTipsSpannable

        initOkiloProcessStepContactListView()
    }

    override fun setupOkiloEventListeners() {
    }

    override fun loadOkiloData() {
        val currentStepItem = stepItem ?: return
        val binding = _binding ?: return
        binding.okiloProcessStepTitle.text = currentStepItem.optString("showTitle")

        //是否支持通讯录选择联系人
        val isContactPick = isOkiloContactPickSupported()
        //联系人关系关键字
        val relationOtherKey = currentStepItem.optString("relationOtherKey",getString(R.string.okilo_process_step_contact_info_relation_other))
        val relationOtherHint = currentStepItem.optString("relationOtherHint",getString(R.string.okilo_process_step_contact_info_relation_other_hint))

//        val dataList = arrayListOf<JSONObject>()
//        // TODO: 这里dataList需要深拷贝，否则列表会共用一个数据源
//        val stringCopy = OkiloDeepCopyUtil(currentStepItem.optString("dataList"))
//        for (i in 0..< currentStepItem.optInt("itemCount")){
//            val obj = JSONObject()
//            val dataArray = JSONArray(stringCopy.content)
//            for (j in 0..<dataArray.length()){
//                val dataObj = dataArray.optJSONObject(j)
//                dataObj.put("isContactPick",isContactPick)
//                when(dataObj.optString("action")){
//                    "CONTACT_GROUP_RELATION" -> {
//                        val relationShips = currentStepItem.optJSONArray("relationShips")
//                        val valueArray = relationShips?.optJSONArray(i)
//                        val values = JSONArray()
//                        valueArray?.let { array ->
//                            for (n in 0..< array.length()) {
//                                val value = JSONObject()
//                                value.put("title", array.optString(n))
//                                value.put("value", array.optString(n))
//                                values.put(value)
//                            }
//                        }
//                        dataObj.put("values", values)
//                        dataObj.put("relationOtherKey",relationOtherKey)
//                        dataObj.put("relationOtherHint",relationOtherHint)
//                    }
//
//                    "CONTACT_GROUP_PHONE" -> {//联系人电话
//                        dataObj.put("action","CONTACT_GROUP_PHONE")
//                    }
//
//                    "CONTACT_GROUP_NAME" -> {//联系人姓名
//                        dataObj.put("action","CONTACT_GROUP_PHONE")
//                    }
//
//                    else -> {
//                        dataObj.put("action","INPUT")
//                    }
//                }
//            }
//            obj.put("stepTitle",pageName)
//            obj.put("dataList",dataArray)
//            dataList.add(obj)
//        }
        val dataList = buildDataList(currentStepItem, isContactPick, relationOtherKey, relationOtherHint)
        contactAdapter?.data = dataList
    }

    /**
     * 构建联系人数据
     */
    private fun buildDataList(currentStepItem: JSONObject, isContactPick: Boolean, relationOtherKey: String, relationOtherHint: String): ArrayList<JSONObject> {
        val itemCount = currentStepItem.optInt("itemCount")
        val dataList = ArrayList<JSONObject>(itemCount)

        // 深拷贝数据，避免数据错乱
        val originalDataArray = getDeepCopiedDataArray(currentStepItem) ?: return dataList

        //联系人数据总数量
        for (i in 0 until itemCount) {
            val processedArray = processDataArray(originalDataArray, i, isContactPick, currentStepItem, relationOtherKey, relationOtherHint)
            dataList.add(JSONObject().apply {
                put("stepTitle", pageName)
                put("dataList", processedArray)
            })
        }
        return dataList
    }

    /**
     * 创建新实例，避免数据错乱
     */
    private fun getDeepCopiedDataArray(currentStepItem: JSONObject): JSONArray? {
        return try {
            val jsonString = currentStepItem.optString("dataList")
            if (jsonString.isNotEmpty()) {
                JSONArray(jsonString)
            } else {
                null
            }
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 处理单个联系人数据
     */
    private fun processDataArray(dataArray: JSONArray, index: Int, isContactPick: Boolean, currentStepItem: JSONObject, relationOtherKey: String, relationOtherHint: String): JSONArray {
        val resultArray = JSONArray()
        //联系人信息：姓名、电话、关系
        for (j in 0 until dataArray.length()) {
            val dataObj = dataArray.optJSONObject(j) ?: continue

            // 创建新对象避免修改原始数据
            val processedObj = JSONObject(dataObj.toString()).apply {
                put("isContactPick", isContactPick)
                processActionType(this, index, currentStepItem, relationOtherKey, relationOtherHint)
            }
            resultArray.put(processedObj)
        }
        return resultArray
    }

    /**
     * 处理联系电话、姓名、关系
     */
    private fun processActionType(dataObj: JSONObject, index: Int, currentStepItem: JSONObject, relationOtherKey: String, relationOtherHint: String) {
        when (dataObj.optString("action")) {
            "CONTACT_GROUP_RELATION" -> {
                processContactGroupRelation(dataObj, index, currentStepItem, relationOtherKey, relationOtherHint)
            }
            "CONTACT_GROUP_PHONE",
            "CONTACT_GROUP_NAME" -> {
                dataObj.put("action", "CONTACT_GROUP_PHONE")
            }
            else -> {
                dataObj.put("action", "INPUT")
            }
        }
    }

    /**
     * 处理联系人关系选项
     */
    private fun processContactGroupRelation(dataObj: JSONObject, index: Int, currentStepItem: JSONObject, relationOtherKey: String, relationOtherHint: String) {
        val relationShips = currentStepItem.optJSONArray("relationShips")
        val valueArray = relationShips?.optJSONArray(index)
        val values = JSONArray()
        valueArray?.let { array ->
            for (n in 0 until array.length()) {
                values.put(JSONObject().apply {
                    put("title", array.optString(n))
                    put("value", array.optString(n))
                })
            }
        }
        dataObj.apply {
            put("values", values)
            put("relationOtherKey", relationOtherKey)
            put("relationOtherHint", relationOtherHint)
        }
    }

    /**
     * 初始化Views
     */
    private fun initOkiloProcessStepContactListView(){
        _binding?.okiloProcessStepContactListView?.setHasFixedSize(true)
        _binding?.okiloProcessStepContactListView?.isNestedScrollingEnabled = false
        _binding?.okiloProcessStepContactListView?.isFocusableInTouchMode = false //不需要焦点
        val layoutManager = LinearLayoutManager(context)
        layoutManager.orientation = RecyclerView.VERTICAL
        _binding?.okiloProcessStepContactListView?.layoutManager = layoutManager
        val topDecoration = OkiloDensityUtil.dp2px(14f)
        _binding?.okiloProcessStepContactListView?.addItemDecoration(
            LinearSpacingItemDecoration(
                0,
                0,
                topDecoration,
                0
            )
        )
        contactAdapter =
            OkiloStepContactApt(_binding?.root, _binding?.okiloProcessStepContactListView)
        _binding?.okiloProcessStepContactListView?.adapter = contactAdapter
        _binding?.okiloProcessStepContactListView?.itemAnimator = DefaultItemAnimator()
        contactAdapter?.setOnChildItemSelectMobileListener(object : OkiloStepContactApt.IChildItemSelectMobileListener{
            override fun onChildSelectMobileClick(parentPosition: Int, childModel: JSONObject) {
                val startTime = System.currentTimeMillis()
                authStepAct?.pickContact?.startPickContact { contactName, contactMobile ->
                    OkiloLog.i(">>>>>>>>>>>>>>>>>>>>>$contactName>>>>>>>$contactMobile")
                    val subTimestamp = System.currentTimeMillis() - startTime

                    contactAdapter?.apply {
                        val parentItem = getItem(parentPosition)
                        updateContactData(parentItem, contactName, contactMobile, subTimestamp, parentPosition)
                        notifyItemChanged(parentPosition)
                    }

//                    contactAdapter?.let {
//                        val parentItem = it.getItem(parentPosition)
//
//                        //设置联系人名称
//                        val dataArray = parentItem.optJSONArray("dataList")
//                        if (dataArray != null) {
//                            for (i in 0..<dataArray.length()) {
//                                val itemObj = dataArray.optJSONObject(i)
//                                if (itemObj.optString("paramName") == "fullName"){
//                                    val obj = JSONObject()
//                                    obj.put("title",contactName)
//                                    obj.put("value",contactName)
//                                    itemObj.put("selectItem",obj)
//                                    val subRemark = "${contactName}$$${subTimestamp}"
//                                    addEventPointRequestAction(String.format(OkiloEventPointType.OKILO_TRACK_CLICK.STEP_XX_SELECT, "${parentItem.optString("stepTitle")}_${itemObj.optString("paramName")}_${parentPosition+1}"), subRemark)
//                                    continue
//                                }
//                                if (itemObj.optString("paramName") == "mobile"){
//                                    val obj = JSONObject()
//                                    obj.put("title",contactMobile)
//                                    obj.put("value",contactMobile)
//                                    itemObj.put("selectItem",obj)
//                                    val subRemark = "${contactMobile}$$${subTimestamp}"
//                                    addEventPointRequestAction(String.format(OkiloEventPointType.OKILO_TRACK_CLICK.STEP_XX_SELECT, "${parentItem.optString("stepTitle")}_${itemObj.optString("paramName")}_${parentPosition+1}"), subRemark)
//                                    continue
//                                }
//                            }
//                        }
//                        it.notifyItemChanged(parentPosition)
//                    }
                }
            }
        })
    }

    /**
     * 更新联系人电话和姓名
     */
    private fun updateContactData(parentItem: JSONObject, contactName: String, contactMobile: String, subTimestamp: Long, parentPosition: Int) {
        val dataArray = parentItem.optJSONArray("dataList") ?: return
        for (i in 0 until dataArray.length()) {
            val itemObj = dataArray.optJSONObject(i) ?: continue
            when (itemObj.optString("paramName")) {
                "fullName" -> {
                    updateContactItem(itemObj, contactName, "fullName", parentItem, parentPosition, subTimestamp)
                }
                "mobile" -> {
                    updateContactItem(itemObj, contactMobile, "mobile", parentItem, parentPosition, subTimestamp)
                }
            }
        }
    }

    /**
     * 更新 selectItem 数据
     */
    private fun updateContactItem(itemObj: JSONObject, value: String, paramName: String, parentItem: JSONObject, parentPosition: Int, subTimestamp: Long) {
        itemObj.put("selectItem", JSONObject().apply {
            put("title", value)
            put("value", value)
        })
        reportContactSelectionEvent(value, paramName, parentItem, parentPosition, subTimestamp)
    }

    /**
     * 添加埋点
     */
    private fun reportContactSelectionEvent(value: String, paramName: String, parentItem: JSONObject, parentPosition: Int, subTimestamp: Long) {
        val subRemark = "${value}$$${subTimestamp}"
        val eventKey = "${parentItem.optString("stepTitle")}_${paramName}_${parentPosition + 1}"
        addEventPointRequestAction(String.Companion.format(OkiloEventPointType.OKILO_CLICK_TRACK.STEP_XX_SELECT, eventKey), subRemark)
    }

    /**
     * 检查是否填写完整
     * 当且仅当 isMust=”NO“为非必填
     */
    private fun isAllowContactSubmit(): Boolean{
//        val dataList = arrayListOf<JSONObject>()
//        contactAdapter?.let {
//            for (i in 0..< it.itemCount){
//                val dataArray = it.getItem(i).optJSONArray("dataList")
//                dataArray?.let { array ->
//                    for (j in 0..< array.length()){
//                        val item = array.optJSONObject(j)
//                        dataList.add(item)
//                    }
//                }
//            }
//        }
//        //是否允许提交
//        var isAllow = true
//        for (i in 0..<dataList.size){
//            val item = dataList[i]
//            //存在 isMust && isMust == ”NO“  非必填
//            if (item.has("isMust") && item.optString("isMust") == "NO"){
//                continue
//            }
//            //必填 && 没有内容 || 内容为空
//            if (!item.has("selectItem")){
//                isAllow = false
//                break
//            }
//            val selectItem = item.optJSONObject("selectItem")
//            if (selectItem == null){
//                isAllow = false
//                break
//            }
//            val paramName = item.optString("paramName")
//            val paramValue = selectItem.optString("value")
//            if (paramValue.isEmpty()){
//                isAllow = false
//                break
//            }
//            if (paramName == "relation" && paramValue == item.optString("relationOtherKey") && selectItem.optString("otherValue","").isEmpty()){
//                isAllow = false
//                break
//            }
//        }
//        return isAllow

        val adapter = contactAdapter ?: return false
        for (i in 0 until adapter.itemCount) {
            val dataArray = adapter.getItem(i).optJSONArray("dataList") ?: continue

            for (j in 0 until dataArray.length()) {
                val dataItem = dataArray.optJSONObject(j)
                if (!isValidContactItem(dataItem)) {
                    return false
                }
            }
        }

        return true
    }

    private fun isValidContactItem(item: JSONObject): Boolean {
        // 非必填项直接通过验证
        if (item.optString("isMust") == "NO") return true

        val selectItem = item.optJSONObject("selectItem") ?: return false
        val paramValue = selectItem.optString("value")

        // 检查必填项是否有有效内容
        if (paramValue.isEmpty()) return false

        // 特殊验证：关系字段如果选择"其他"，需要填写其他值
        val paramName = item.optString("paramName")
        if (paramName == "relation" && paramValue == item.optString("relationOtherKey")) {
            return selectItem.optString("otherValue").isNotEmpty()
        }

        return true
    }

    /**
     * 是否支持通讯录选择
     */
    private fun isOkiloContactPickSupported(): Boolean{
        val intentContact =
            Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI)
        val resolveInfoCType = getAct().packageManager.resolveActivity(intentContact, PackageManager.MATCH_DEFAULT_ONLY)
        return resolveInfoCType != null
    }

    /**
     * 是否全为数字
     */
    private fun iOkiloCheckAllNumber(text: String?): Boolean {
        if (text.isNullOrEmpty()){
            return false
        }
        val formatLct = "^-?\\d+\\.?\\d*$"
        val patternLct = Pattern.compile(formatLct)
        return patternLct.matcher(text.trim()).matches()
    }

    /**
     * 提交联系人信息
     */
    fun subOkiloProcessStepContactInfo(){
        val currentStepItem = stepItem ?: return
        _binding?.root?.clearFocus()

        if (!isAllowContactSubmit()){
            showErrorTipsDialog(getString(R.string.okilo_dlog_tips_submit_error), pageName)
            return
        }

        val params = JSONObject().addParams().apply {
            put("path",currentStepItem.optString("apiUrl").replace("/",""))
        }
        //构建联系人参数
        val paramArray = buildContactParamArray()
        params.put(currentStepItem.optString("contactParamName"), paramArray)

        //拼接上传数据格式
//        val paramArray = JSONArray()
//        contactAdapter?.let { adapter ->
//            for (i in 0..< adapter.itemCount){
//                val obj = JSONObject()
//                val dataArray = adapter.getItem(i).optJSONArray("dataList")
//                dataArray?.let {
//                    for (j in 0..< it.length()){
//                        val item = it.optJSONObject(j)
//                        val paramName = item.optString("paramName")
//                        val selectItem = item.optJSONObject("selectItem")
//                        var paramValue = selectItem?.optString("value")
//                        if (paramName == "relation" && paramValue == item.optString("relationOtherKey")){
//                            paramValue = selectItem?.optString("otherValue")
//                            //如果关系为“Other”，输入的内容为纯数字，则直接传“Other”
//                            if (iOkiloCheckAllNumber(paramValue)){
//                                paramValue = item.optString("relationOtherKey")
//                            }
//                        }
//                        obj.put(paramName,paramValue)
//                    }
//                }
//                paramArray.put(obj)
//            }
//        }
//        params.put(currentStepItem.optString("contactParamName"),paramArray)

        addEventPointRequestAction(String.Companion.format(OkiloEventPointType.OKILO_CLICK_TRACK.STEP_XX_NEXT, pageName),"")
        // TODO: 进件信息点下一步 需上报所有埋点
        OkiloPointManager.getInstance().manualReport()
        authStepAct?.sOkiloProcessStepSubmitAction(params)
    }

    /**
     * 构建联系人参数数组
     */
    private fun buildContactParamArray(): JSONArray {
        val paramArray = JSONArray()
        contactAdapter?.let { adapter ->
            for (i in 0..<adapter.itemCount) {
                val contactData = adapter.getItem(i)
                val contactObj = buildContactObject(contactData.optJSONArray("dataList"))
                paramArray.put(contactObj)
            }
        }
        return paramArray
    }

    /**
     * 构建单个联系人对象
     */
    private fun buildContactObject(dataArray: JSONArray?): JSONObject {
        val obj = JSONObject()
        dataArray ?: return obj
        for (j in 0..<dataArray.length()) {
            val item = dataArray.optJSONObject(j)
            val paramName = item.optString("paramName")
            val paramValue = getProcessedParamValue(item)
            obj.put(paramName, paramValue)
        }
        return obj
    }

    /**
     * 处理参数值，relation字段的特殊逻辑
     */
    private fun getProcessedParamValue(item: JSONObject): String? {
        val selectItem = item.optJSONObject("selectItem") ?: return null
        var paramValue = selectItem.optString("value")

        if (item.optString("paramName") == "relation" && paramValue == item.optString("relationOtherKey")) {
            paramValue = selectItem.optString("otherValue").let { otherValue ->
                //如果关系为“Other”，输入的内容为纯数字，则直接传“Other”
                if (iOkiloCheckAllNumber(otherValue)) {
                    item.optString("relationOtherKey") // 返回 "Other"
                } else {
                    otherValue
                }
            }
        }

        return paramValue
    }

    override fun onOkiloPublishEvent(event: OkiloEventData) {
        super.onOkiloPublishEvent(event)
        when(event.eventType){
            OkiloEventData.TYPE.OKILO_PROCESS_STEP_SUBMIT -> {
                subOkiloProcessStepContactInfo()
            }
            else -> {

            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}